//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __CBASICDIRECTORY_H__
#define __CBASICDIRECTORY_H__

#include <Wintypes.h>
#include <elasys_server.h>
#include <linknode.h>
#include <Aura.h>
#include "CBasicFile.h"

class CBasicDirectory : public IBasicDirectory, IFileMonitor, public DLinkNode
{
public:
    CARAPI_(PInterface) Probe(
         /* [in]  */ REIID riid);

    CARAPI_(UInt32) AddRef(void);

    CARAPI_(UInt32) Release(void);

    CARAPI Aggregate(
        /* [in] */ AggrType aggrType,
        /* [in] */ PInterface pObject);

    CARAPI GetDomain(
         /* [out] */ PInterface *ppObj);

    CARAPI Sync();

    CARAPI GetType(
        /* [out] */ FileType * pType);

    CARAPI GetAccessTime(
        /* [out] */ Int32 * pTime);

    CARAPI SetAccessTime(
        /* [in] */ Int32 time);

    CARAPI GetModificationTime(
        /* [out] */ Int32 * pTime);

    CARAPI SetModificationTime(
        /* [in] */ Int32 time);

    CARAPI GetCreateTime(
        /* [out] */ Int32 * pTime);

    CARAPI CheckAccessMode(
        /* [in] */ FileAccessMode mode);

    CARAPI GetAccessMode(
        /* [out] */ FileAccessMode * pMode);

    CARAPI SetAccessMode(
        /* [in] */ FileAccessMode mode);

    CARAPI GetShareMode(
        /* [out] */ FileShareMode *pMode);

    CARAPI SetShareMode(
        /* [in] */ FileShareMode mode);

    CARAPI Lookup(
        /* [in] */ WString name,
        /* [out] */ IBasicFile ** piBasicFile);

    CARAPI CreateFile(
        /* [in] */ WString name,
        /* [in] */ FileAccessMode cmode,
        /* [in] */ Boolean bExclusive,
        /* [out] */ IBasicFile ** piBasicFile);

    CARAPI DeleteFile(
        /* [in] */ WString name);

    CARAPI Rename(
        /* [in] */ WString oldName,
        /* [in] */ IBasicDirectory * pNewDir,
        /* [in] */ WString newName);

    CARAPI CreateDirectory(
        /* [in] */ WString name,
        /* [in] */ FileAccessMode mode);

    CARAPI DeleteDirectory(
        /* [in] */ WString name);

    CARAPI GetDirEntries(
        /* [out] */ IWStringEnumerator ** ppiEnumerator);

    CARAPI MakeFullName(
         /* [in] */  WString name,
         /* [out] */ wchar_t *fullname);

    CARAPI AddFileMonitor(
        /* [out] */ IEvent **pEvent);

    CARAPI RemoveFileMonitor(
        /* [in] */ IEvent *pEvent);

public:
    CBasicDirectory(IBasicDirectory *pParent);
    virtual ~CBasicDirectory();
    ECode Initialize(WString dirName);
    wchar_t *GetDirName(void) const;
    Aura_Handle GetDirObjectListLock();
    Aura_Handle GetFileObjectListLock();

private:
    ECode CheckFileType(wchar_t *wcsName, Boolean *isExist, Boolean *isDir);
    CBasicDirectory * LookUpDirObject(wchar_t *wcsName);
    CBasicFile * LookUpFileObject(wchar_t *wcsName);
    ECode GetDirTime();

private:
    wchar_t *m_pDirName;

    Int32 m_CreateTime;
    Int32 m_LastAccessTime;
    Int32 m_LastModifyTime;

    Interlocked m_cRef;

    DLinkNode m_DirObjectList;
    DLinkNode m_FileObjectList;

    BOOL m_IsRootDir;

    Aura_Handle m_hDirListLock;
    Aura_Handle m_hFileListLock;
    Aura_Handle m_hFileLock;
    Aura_Handle m_hParentDirListLock;

    IBasicDirectory *m_pParentDir;

    FileAccessMode m_DirAccessMode;
    FileShareMode m_DirShareMode;
};

#endif
